home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Sprite 1984 - 1993
/
Sprite 1984 - 1993.iso
/
src
/
machserver
/
1.098
/
mach
/
sun4c.md
/
unpack.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-08-17
|
5KB
|
221 lines
#ifdef sccsid
static char sccsid[] = "@(#)unpack.c 1.5 88/02/08 Copyr 1987 Sun Micro";
#endif
/*
* Copyright (c) 1987 by Sun Microsystems, Inc.
*/
/* Unpack procedures for Sparc FPU simulator. */
/*
* This whole file refuses to lint.
*/
#ifndef lint
#include <sun4/fpu/fpu_simulator.h>
#include <sun4/fpu/globals.h>
PRIVATE void
leftshift(pu, n)
unpacked *pu;
unsigned n;
/* Left shift significand by n bits. Affect all classes. */
{
while (n >= 32) { /* big shift */
(*pu).significand[0] = (*pu).significand[1];
(*pu).significand[1] = (*pu).significand[2];
(*pu).significand[2] = 0;
n -= 32;
}
while (n > 0) { /* small shift */
pu->significand[0] = pu->significand[0] << 1;
if (pu->significand[1] & 0x80000000)
pu->significand[0] |= 1;
pu->significand[1] = pu->significand[1] << 1;
if (pu->significand[2] & 0x80000000)
pu->significand[1] |= 1;
pu->significand[2] = pu->significand[2] << 1;
n -= 1;
}
}
PRIVATE void
unpackinteger(pu, x)
unpacked *pu; /* unpacked result */
int x; /* packed integer */
{
if (x == 0) {
pu->sign = 0;
pu->fpclass = fp_zero;
} else {
(*pu).sign = x < 0;
(*pu).fpclass = fp_normal;
(*pu).exponent = INTEGER_BIAS;
(*pu).significand[0] = (x >= 0) ? x : -x;
(*pu).significand[1] = 0;
(*pu).significand[2] = 0;
fpu_normalize(pu);
}
}
void
unpacksingle(pu, x)
unpacked *pu; /* unpacked result */
single_type x; /* packed single */
{
(*pu).sign = x.sign;
pu->significand[1] = 0;
pu->significand[2] = 0;
if (x.exponent == 0) { /* zero or sub */
if (x.significand == 0) { /* zero */
pu->fpclass = fp_zero;
return;
} else { /* subnormal */
pu->fpclass = fp_normal;
pu->exponent = -SINGLE_BIAS;
pu->significand[0] = x.significand << 9;
fpu_normalize(pu);
return;
}
} else if (x.exponent == 0xff) { /* inf or nan */
if (x.significand == 0) { /* inf */
pu->fpclass = fp_infinity;
return;
} else { /* nan */
if ((x.significand & 0x400000) != 0) { /* quiet */
pu->fpclass = fp_quiet;
} else {/* signaling */
pu->fpclass = fp_signaling;
fpu_set_exception(fp_invalid);
}
pu->significand[0] = 0x40000000 | (x.significand << 8);
return;
}
}
(*pu).exponent = x.exponent - SINGLE_BIAS;
(*pu).fpclass = fp_normal;
(*pu).significand[0] = 0x80000000 | (x.significand << 8);
}
void
unpackdouble(pu, x, y)
unpacked *pu; /* unpacked result */
double_type x; /* packed double */
unsigned y;
{
(*pu).sign = x.sign;
pu->significand[1] = y;
pu->significand[2] = 0;
if (x.exponent == 0) { /* zero or sub */
if ((x.significand == 0) && (y == 0)) { /* zero */
pu->fpclass = fp_zero;
return;
} else { /* subnormal */
pu->fpclass = fp_normal;
pu->exponent = 12 - DOUBLE_BIAS;
pu->significand[0] = x.significand;
fpu_normalize(pu);
return;
}
} else if (x.exponent == 0x7ff) { /* inf or nan */
if ((x.significand == 0) && (y == 0)) { /* inf */
pu->fpclass = fp_infinity;
return;
} else { /* nan */
if ((x.significand & 0x80000) != 0) { /* quiet */
pu->fpclass = fp_quiet;
} else {/* signaling */
pu->fpclass = fp_signaling;
fpu_set_exception(fp_invalid);
}
pu->significand[0] = 0x80000 | x.significand;
leftshift(pu, 11);
return;
}
}
(*pu).exponent = x.exponent - DOUBLE_BIAS;
(*pu).fpclass = fp_normal;
(*pu).significand[0] = 0x100000 | x.significand;
leftshift(pu, 11);
}
PRIVATE void
unpackextended(pu, x, y, z)
unpacked *pu; /* unpacked result */
extended_type x; /* packed extended */
unsigned y, z;
{
(*pu).sign = x.sign;
(*pu).fpclass = fp_normal;
(*pu).exponent = x.exponent - EXTENDED_BIAS;
(*pu).significand[0] = y;
(*pu).significand[1] = z;
(*pu).significand[2] = 0;
if (x.exponent < 0x7fff) { /* zero, normal, or subnormal */
if ((z == 0) && (y == 0)) { /* zero */
pu->fpclass = fp_zero;
return;
} else { /* normal or subnormal */
fpu_normalize(pu);
return;
}
} else { /* inf or nan */
if ((z == 0) && (y == 0)) { /* inf */
pu->fpclass = fp_infinity;
return;
} else { /* nan */
if ((y & 0x40000000) != 0) { /* quiet */
pu->fpclass = fp_quiet;
} else {/* signaling */
pu->fpclass = fp_signaling;
fpu_set_exception(fp_invalid);
}
pu->significand[0] |= 0x40000000; /* make quiet */
return;
}
}
}
void
_fp_unpack(pu, n, dtype)
unpacked *pu; /* unpacked result */
unsigned n; /* register where data starts */
enum fp_op_type dtype; /* type of datum */
{
freg_type f, fy, fz;
switch ((int) dtype) {
case fp_op_integer:
_fp_current_read_freg(&f, n);
unpackinteger(pu, f.int_reg);
break;
case fp_op_single:
_fp_current_read_freg(&f, n);
unpacksingle(pu, f.single_reg);
break;
case fp_op_double:
_fp_current_read_freg(&f, DOUBLE_E(n));
_fp_current_read_freg(&fy, DOUBLE_F(n));
unpackdouble(pu, f.double_reg, fy.unsigned_reg);
break;
case fp_op_extended:
_fp_current_read_freg(&f, EXTENDED_E(n));
_fp_current_read_freg(&fy, EXTENDED_F(n));
_fp_current_read_freg(&fz, EXTENDED_FLOW(n));
unpackextended(pu, f.extended_reg, fy.unsigned_reg, fz.unsigned_reg);
break;
}
}
void
_fp_unpack_word(pu, n)
unsigned *pu; /* unpacked result */
unsigned n; /* register where data starts */
{
_fp_current_read_freg(pu, n);
}
#endif /* lint */